{
 "cells": [
  {
   "cell_type": "code",
   "execution_count": 1,
   "id": "b8aada92",
   "metadata": {},
   "outputs": [],
   "source": [
    "%matplotlib inline\n",
    "import matplotlib.pyplot as plt\n",
    "import matplotlib.dates as dates\n",
    "import math\n",
    "\n",
    "import numpy as np\n",
    "import datetime\n",
    "from IPython.display import display\n",
    "import pandas as pd\n",
    "\n",
    "from garmindb import GarminConnectConfigManager\n",
    "from garmindb.garmindb import GarminSummaryDb, DaysSummary, MonitoringDb, MonitoringHeartRate, Sleep, GarminDb\n",
    "from garmindb.summarydb import DaysSummary, SummaryDb\n",
    "\n",
    "from jupyter_funcs import format_number\n",
    "from graphs import Graph"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "id": "2d38e0f7-2ee5-40df-9373-b6485798d541",
   "metadata": {},
   "outputs": [],
   "source": [
    "def minsFromTime(t):\n",
    "    return float(t.hour * 3600 + t.minute * 60 + t.second) / 60.0"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "id": "7353aa53-92a0-44d9-b476-e050295c4748",
   "metadata": {},
   "outputs": [],
   "source": [
    "# start date\n",
    "start_ts = datetime.datetime.combine(datetime.date(year=2022, month=5, day=1), datetime.datetime.min.time())\n",
    "# end date (today)\n",
    "end_ts = datetime.datetime.combine(datetime.date.today(), datetime.datetime.max.time())\n",
    "\n",
    "gc_config = GarminConnectConfigManager()\n",
    "db_params = gc_config.get_db_params()\n",
    "\n",
    "garmin_db = GarminDb(db_params)\n",
    "sum_db = SummaryDb(db_params, False)\n",
    "data = DaysSummary.get_for_period(sum_db, start_ts, end_ts, DaysSummary)\n",
    "sleep = Sleep.get_for_period(garmin_db, start_ts, end_ts)\n",
    "\n",
    "time = [entry.day for entry in data]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "id": "e41203c2-d435-4045-9c84-3559b4d3b367",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>Date</th>\n",
       "      <th>stress_avg</th>\n",
       "      <th>bb_max</th>\n",
       "      <th>bb_min</th>\n",
       "      <th>rem_sleep_max</th>\n",
       "      <th>deep_sleep</th>\n",
       "      <th>sleep_avg</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>0</th>\n",
       "      <td>2022-05-02</td>\n",
       "      <td>18</td>\n",
       "      <td>80</td>\n",
       "      <td>23</td>\n",
       "      <td>13.0</td>\n",
       "      <td>106.0</td>\n",
       "      <td>7.616667</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>1</th>\n",
       "      <td>2022-05-03</td>\n",
       "      <td>36</td>\n",
       "      <td>100</td>\n",
       "      <td>18</td>\n",
       "      <td>94.0</td>\n",
       "      <td>24.0</td>\n",
       "      <td>8.533333</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2</th>\n",
       "      <td>2022-05-04</td>\n",
       "      <td>31</td>\n",
       "      <td>70</td>\n",
       "      <td>21</td>\n",
       "      <td>110.0</td>\n",
       "      <td>0.0</td>\n",
       "      <td>7.666667</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>3</th>\n",
       "      <td>2022-05-05</td>\n",
       "      <td>32</td>\n",
       "      <td>63</td>\n",
       "      <td>18</td>\n",
       "      <td>74.0</td>\n",
       "      <td>31.0</td>\n",
       "      <td>6.416667</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>4</th>\n",
       "      <td>2022-05-06</td>\n",
       "      <td>36</td>\n",
       "      <td>93</td>\n",
       "      <td>14</td>\n",
       "      <td>111.0</td>\n",
       "      <td>14.0</td>\n",
       "      <td>8.933333</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>...</th>\n",
       "      <td>...</td>\n",
       "      <td>...</td>\n",
       "      <td>...</td>\n",
       "      <td>...</td>\n",
       "      <td>...</td>\n",
       "      <td>...</td>\n",
       "      <td>...</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>653</th>\n",
       "      <td>2024-02-14</td>\n",
       "      <td>47</td>\n",
       "      <td>65</td>\n",
       "      <td>5</td>\n",
       "      <td>52.0</td>\n",
       "      <td>None</td>\n",
       "      <td>6.183333</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>654</th>\n",
       "      <td>2024-02-15</td>\n",
       "      <td>41</td>\n",
       "      <td>20</td>\n",
       "      <td>5</td>\n",
       "      <td>0.0</td>\n",
       "      <td>None</td>\n",
       "      <td>4.3</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>655</th>\n",
       "      <td>2024-02-16</td>\n",
       "      <td>30</td>\n",
       "      <td>52</td>\n",
       "      <td>21</td>\n",
       "      <td>10.0</td>\n",
       "      <td>None</td>\n",
       "      <td>7.266667</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>656</th>\n",
       "      <td>2024-02-17</td>\n",
       "      <td>39</td>\n",
       "      <td>71</td>\n",
       "      <td>12</td>\n",
       "      <td>15.0</td>\n",
       "      <td>None</td>\n",
       "      <td>6.333333</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>657</th>\n",
       "      <td>2024-02-18</td>\n",
       "      <td>45</td>\n",
       "      <td>34</td>\n",
       "      <td>5</td>\n",
       "      <td>0.0</td>\n",
       "      <td>None</td>\n",
       "      <td>7.15</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "<p>658 rows × 7 columns</p>\n",
       "</div>"
      ],
      "text/plain": [
       "           Date stress_avg bb_max bb_min rem_sleep_max deep_sleep sleep_avg\n",
       "0    2022-05-02         18     80     23          13.0      106.0  7.616667\n",
       "1    2022-05-03         36    100     18          94.0       24.0  8.533333\n",
       "2    2022-05-04         31     70     21         110.0        0.0  7.666667\n",
       "3    2022-05-05         32     63     18          74.0       31.0  6.416667\n",
       "4    2022-05-06         36     93     14         111.0       14.0  8.933333\n",
       "..          ...        ...    ...    ...           ...        ...       ...\n",
       "653  2024-02-14         47     65      5          52.0       None  6.183333\n",
       "654  2024-02-15         41     20      5           0.0       None       4.3\n",
       "655  2024-02-16         30     52     21          10.0       None  7.266667\n",
       "656  2024-02-17         39     71     12          15.0       None  6.333333\n",
       "657  2024-02-18         45     34      5           0.0       None      7.15\n",
       "\n",
       "[658 rows x 7 columns]"
      ]
     },
     "execution_count": 4,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "stress_avg = [entry.stress_avg for entry in data]\n",
    "bb_max = [entry.bb_max for entry in data]\n",
    "bb_min = [entry.bb_min for entry in data]\n",
    "rem_sleep_max = [minsFromTime(entry.rem_sleep_avg) for entry in data]\n",
    "sleep_avg = [minsFromTime(entry.sleep_avg) / 60 for entry in data]\n",
    "deep_sleep = [minsFromTime(sleep_event.deep_sleep) for sleep_event in sleep]\n",
    "dm_df = pd.DataFrame([time, stress_avg, bb_max, bb_min, rem_sleep_max,deep_sleep, sleep_avg]).T\n",
    "dm_df.columns = [\"Date\", \"stress_avg\", \"bb_max\", \"bb_min\", \"rem_sleep_max\", \"deep_sleep\", \"sleep_avg\"]\n",
    "# remove the last record 'cause it's noisy sometimes\n",
    "dm_df.drop(dm_df.tail(1).index,inplace=True) \n",
    "dm_df\n",
    "\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "ed0fe315",
   "metadata": {},
   "outputs": [],
   "source": [
    "\n",
    "\n",
    "columns = { \"stress_avg\" : \n",
    "                   {\n",
    "                       \"label\": \"Stress average\",\n",
    "                       \"trend_marker\": \"--\",\n",
    "                       \"color\": \"red\"\n",
    "\n",
    "                   }, \n",
    "            \"bb_max\": \n",
    "                   {\n",
    "                       \"label\": \"Body battery max\",\n",
    "                       \"trend_marker\": \"--\",\n",
    "                       \"color\": \"orange\"\n",
    "                   },\n",
    "           \n",
    "            \"sleep_avg\": \n",
    "                   {\n",
    "                       \"label\": \"Sleep time (hrs)\",\n",
    "                       \"trend_marker\": \"-.\",\n",
    "                       \"color\": \"blue\"\n",
    "                  },\n",
    "            \"rem_sleep_max\": \n",
    "                   {\n",
    "                       \"label\": \"Rem Sleep time (mins)\",\n",
    "                       \"trend_marker\": \"-\",\n",
    "                       \"color\": \"purple\"\n",
    "                   },\n",
    "           \n",
    "            \"deep_sleep\": \n",
    "                   {\n",
    "                       \"label\": \"Deep sleep (mins)\",\n",
    "                       \"trend_marker\": \"-\",\n",
    "                       \"color\": \"green\"\n",
    "                   }\n",
    "          }\n",
    "\n",
    "# these are the data columns to plot\n",
    "show_cols = {\"deep_sleep\", \"stress_avg\", \"bb_max\"}\n",
    "\n",
    "fig, host = plt.subplots(figsize=(22,16))\n",
    "\n",
    "plots = []\n",
    "fit_summary = []\n",
    "step = 0\n",
    "\n",
    "for col in show_cols:\n",
    "    label=columns[col][\"label\"]\n",
    "   \n",
    "    ax2 = host.twinx()\n",
    "    ax2.set_ylabel(label)\n",
    "    ax2.tick_params(axis='y', labelcolor=columns[col][\"color\"])\n",
    "\n",
    "    # data\n",
    "    plot, = ax2.plot(dm_df.Date, dm_df[col], 'o', ms=3.0, color=columns[col][\"color\"], label=label)\n",
    "    plots.append(plot)\n",
    "    \n",
    "    # trend\n",
    "    fitlabel = 'Fit {}'.format(label)\n",
    "    x_dates = dates.date2num(dm_df.Date)\n",
    "    trend = np.polyfit(x_dates, dm_df[col].astype(float) , 1)\n",
    "    fit = np.poly1d(trend)\n",
    "    x_fit = np.linspace(x_dates.min(), x_dates.max())\n",
    "    fit, = ax2.plot(dates.num2date(x_fit), fit(x_fit), linestyle=columns[col][\"trend_marker\"], color=columns[col][\"color\"],label=fitlabel)\n",
    "    plots.append(fit)\n",
    "    \n",
    "    ax2.spines['right'].set_position(('outward', step))\n",
    "    \n",
    "    step = step + 60\n",
    "\n",
    "    fit_data = fit.get_ydata()\n",
    "    \n",
    "    fit_summary.append({\"\": fitlabel, \"min\": math.floor(fit_data.min()), \"max\":math.floor(fit_data.max())})\n",
    "    \n",
    "host.legend(handles=plots, loc='best')\n",
    "\n",
    "col_label = \"\"\n",
    "for col in show_cols:\n",
    "    if len(col_label):\n",
    "        col_label += \", \"\n",
    "    col_label += f\"{col}\"\n",
    "\n",
    "title = f\"{col_label} from {start_ts.date()} to {end_ts.date()}\"\n",
    "\n",
    "plt.title(label=title, fontsize=25)\n",
    "\n",
    "plt.show()\n",
    "pd.DataFrame(fit_summary)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "cab36f4b",
   "metadata": {},
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "interpreter": {
   "hash": "bfd9857ee3bb42c16b52c1ffe04453343fea53c05fc5f9f2d5ac6a881cdaa36c"
  },
  "kernelspec": {
   "display_name": "Python 3.9.10 ('.venv': venv)",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.11.7"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 5
}
